package v1

import (
	"encoding/json"
	"fmt"
	"ginBlog/model"
	"ginBlog/utils/errmsg"
	"ginBlog/utils/validator"
	"github.com/gin-gonic/gin"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"net/http"
	"regexp"
	"strconv"
	"sync"
)

// 新增用户
func AddUser(c *gin.Context) {
	var data model.User
	//	绑定数据模型
	c.ShouldBindJSON(&data)
	// 验证数据是否符合规范
	msg, code := validator.Validate(&data)
	if code != errmsg.SUCCESS {
		c.JSON(http.StatusOK, gin.H{
			"status":  code,
			"message": msg,
		})
		return
	}

	// 判断用户是否存在，不存在则添加
	code = model.CheckUser(data.Username)
	if code == errmsg.SUCCESS {
		model.CreateUser(&data)
	}
	if code == errmsg.ERROR_USERNAME_USED {
		code = errmsg.ERROR_USERNAME_USED
	}

	c.JSON(http.StatusOK, gin.H{
		"status":  code,
		"message": errmsg.GetErrMsg(code),
	})
}

// 查询单个用户
func GetUserInfo(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	data, code := model.GetUser(id)
	c.JSON(http.StatusOK, gin.H{
		"status":  code,
		"data":    data,
		"total":   1,
		"message": errmsg.GetErrMsg(code),
	})

}

// 查询用户列表
func GetUsers(c *gin.Context) {
	pageSize, _ := strconv.Atoi(c.Query("pageSize"))
	pageNum, _ := strconv.Atoi(c.Query("pageNum"))
	username := c.Query("username")
	// 如果木有传值就不使用分页
	if pageSize == 0 {
		pageSize = -1
	}
	if pageNum == 0 {
		pageNum = -1
	}

	data, total := model.GetUsers(username, pageSize, pageNum)
	code := errmsg.SUCCESS

	c.JSON(http.StatusOK, gin.H{
		"status":  code,
		"data":    data,
		"total":   total,
		"message": errmsg.GetErrMsg(code),
	})
}

// 编辑用户
func EditUser(c *gin.Context) {
	var data model.User
	id, _ := strconv.Atoi(c.Param("id"))
	c.ShouldBindJSON(&data)
	code := model.CheckUpUser(id, data.Username)
	if code == errmsg.SUCCESS {
		model.EditUser(id, &data)
	}
	// 如果用户存在不执行
	if code == errmsg.ERROR_USERNAME_USED {
		c.Abort()
	}

	c.JSON(http.StatusOK, gin.H{
		"status":  code,
		"message": errmsg.GetErrMsg(code),
	})
}

// 删除用户
func DeleteUser(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))

	code := model.DeleteUser(id)

	c.JSON(http.StatusOK, gin.H{
		"ststus":  code,
		"message": errmsg.GetErrMsg(code),
	})
}

// 基金估值
func GetJiJin(c *gin.Context) {
	var conf Config
	var msgList []Msg
	var wg sync.WaitGroup
	file, err := ioutil.ReadFile("/Users/victor/go/ginBlog/api/v1/config.yaml")
	if err != nil {
		fmt.Println(err)
	}

	err = yaml.Unmarshal(file, &conf)
	if err != nil {
		fmt.Println(err)
	}
	//fmt.Printf("%+v", conf)

	for _, id := range conf.Id {
		wg.Add(1)
		go func(id string) {
			bUrl := "http://fundgz.1234567.com.cn/js/" + id + ".js"
			msg := parse(bUrl)
			if msg.Fundcode == "" {
				msg.Name = "Not Found"
			}
			msgList = append(msgList, msg)
			wg.Done()
		}(id)
	}
	wg.Wait()
	c.JSON(http.StatusOK, gin.H{
		"data": msgList,
	})
}

const resultRegex = `jsonpgz\((.*?)\);`

type Msg struct {
	Fundcode string `json:"fundcode"`
	Name     string `json:"name"`
	Gszzl    string `json:"gszzl"`
	GzTime   string `json:"gztime"`
}

type Config struct {
	Id []string `yaml:"id"`
}

func parse(bUrl string) Msg {
	result := Msg{}

	client := http.Client{}
	request, err := http.NewRequest("GET", bUrl, nil)
	if err != nil {
		fmt.Println(err)
	}

	request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
	request.Header.Add("Accept-Charset", "UTF-8,*;q=0.5")
	request.Header.Add("Accept-Language", "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7")
	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0")
	request.Header.Add("referer", "http://fund.eastmoney.com")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(err)
		return result
	}
	defer response.Body.Close()

	respBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(err)
		return result
	}

	s := reg(resultRegex, respBody)

	err = json.Unmarshal([]byte(s), &result)
	if err != nil {
		fmt.Println("Umarshal failed:", err)
		return result
	}

	return result
}

func reg(regexString string, content []byte) string {
	Reg := regexp.MustCompile(regexString)
	match := Reg.FindAllSubmatch(content, -1)
	for _, m := range match {
		//fmt.Println("基金ID: ", string(m[1]))
		return string(m[1])
	}
	return ""
}
